define(
  ['dict', 'uitouch', 'sharedc', 'sharedf'],
  function(dict, uitouch, sharedc, sharedf){
    "use strict";
    var opts_brd   = document.getElementById('options');
    var opts_brd_b = document.getElementById('options_block');
    var lbl = document.createElement("label");
    var fnmre = /(.*)?\/(.+)/;
    lbl.style.order = "99";
    opts_brd.textContent = '';
    var toc = document.createElement("div");
    var dtoc = document.createElement("div");
    disable_prop(dtoc);
    toc.id = "toc";
    toc.style.width = "95%";
    dtoc.appendChild(toc);
    opts_brd_b.appendChild(dtoc);
    opts_brd_b.appendChild(lbl);
    var storage = null; 
    try { storage = localStorage } catch(e) {console.warn("localStorage not available");}
    var crstorage = null;
    try{ crstorage = chrome.storage.sync;} catch(e) {console.warn("chrome.storage not available");}
    var type;
    var file = {'name':'empty'};
    var filename = '';
    var currentpp = {'page':0, 'percent':0};
    var datas = {
        dict_src: [['google', 'socket'], "Select dictionary source", 'list-item'],
        dict_db: [['!'], "Dict db (! means all)", 'none'],
        lang_f: ['en', "Translate from", 'none'],
        lang_t: ['ru', "Translate to", 'none'],
        socket_host: ['localhost', "dictd host", 'none'],
        socket_port: ['2628', "dictd port", 'none'],
        dsfile: [[], "Or choose it from list", 'list-item'],
    };
    var showdeps = {
        'google':/lang_f|lang_t/,
        'socket':/socket_host|socket_port|dict_db/,
        'excepts':/dsfile|file|dict_src/
    };
    function draw_deps(el){
        if(el.id!='dict_src') return;
        var ex = showdeps['excepts'];
        var shows = showdeps[el.value];
        if(el.value==='socket') {dict.get_dbs(el.value);}
        if(!shows && !ex) return;
        for(var key in datas){
            if(!ex.test(key) && !shows.test(key)) document.getElementById(key).parentNode.style.display = 'none';
            else if (shows.test(key)) document.getElementById(key).parentNode.style.display = 'list-item';
        }
    }
    var hasStorage = (function() {
      try {
        localStorage.setItem('try', 'try');
        localStorage.removeItem('try');
        return true;
        storage = localStorage;
      } catch(e) {
        return false;
      }
      return false;
    }());
    var values = {};
    function disable_prop(_el){
        _el.addEventListener("touchstart", function(e){e.stopPropagation();}, true);
        _el.addEventListener("touchend", function(e){e.stopPropagation();}, true);
        _el.addEventListener("touchmove", function(e){e.stopPropagation();}, true);
    }
    function create_select(obj, name, elements, key, disp){
        var sel = document.createElement("select");
        var nm  = document.createElement("option");
        var br  = document.createElement("br");
        var sp  = document.createElement("span");
        nm.textContent = name;
        nm.selected = 1;
        nm.disabled = 1;
        sel.appendChild(nm);
        sel.id = key;
        sel.style.width = "80%";
        if(key==="dict_db"){
            sharedc.register('dict', 'got_dbs', function(_txt){add_dbs(sel, nm, _txt);});
        }else if(key==="dsfile"){
                sel.addEventListener("change", 
                                function (event){
                                    var fnm = event.target.options[event.target.selectedIndex].value;
                                    filename = fnm.replace(sharedf.relf, "$2");
                                    sdstorage.get(fnm, function (_file) {
                                                                       file = _file;
                                                                       set_opt('last_file', filename);
                                                                       set_opt(filename+"_time", Date.now());
                                                                       sharedc.exec('options', 'got_file')();} );
                                }, false);
                //sdstorage.parse(sel, obj);
            return sel;
        } 
        sel.addEventListener("change", function(evt){get_config(); draw_deps(evt.target);
                                    var value = evt.target.options[evt.target.selectedIndex].value;
                                    set_opt("sel_"+sel.id, value); 
                                    values[evt.target.id] = value;
                                    dict.init_params({"db": values["dict_db"], "dictionary": values["dict_src"]});
                                    }, false);
        for(var eln in elements){
            var el = document.createElement("option");
            el.textContent = elements[eln];
            el.value = elements[eln];
            sel.appendChild(el);
        }
        disable_prop(sel);
        sp.appendChild(sel);
        sp.style.display=disp;
        obj.appendChild(sp);
        return sel;
    }
    function create_input(obj, name, value, key, disp){
        var sel = document.createElement("label");
        var inp = document.createElement("input");
        var br  = document.createElement("br");
        var sp  = document.createElement("span");
        sp.style.width = "100%";
        sel.textContent = name;
        inp.id = key;
        inp.style.left="4px";
        if(key==="file") {   inp.type = 'file'; //inp.accept="application/epub+zip,text/xml,text/plain";
                             inp.addEventListener("change", function (evt){
                                                            var input = evt.target;
                                                            file = evt.target.files[0];
                                                            filename = file.name.replace(fnmre, "$2");
                                                            set_opt('last_file', filename);
                                                            set_opt(filename+"_time", Date.now());
                                                            sharedc.exec('options', 'got_file')();}, false );
        } else {
            inp.value = value;
            var params = [];
            params.push(inp.id);
            inp.type = 'text';
            inp.addEventListener("change",
                function(evt){get_config(); var input = evt.target; set_opt(input.id, input.value); 
                              dict.init_params({"dictionary": values["dict_src"], "host": values["socket_host"],
                                               "port": parseInt(values["socket_port"]),
                                               "sl": values["lang_f"], "hl": values["lang_t"], "tl": values["lang_t"]});
                              dict.get_dbs(values["dict_src"]);}, false);
            get_opt(params, function(key, value){
                    if(value){ 
                        inp.value = value;
                        try { var evt = new Event('change');}
                        catch (e) { var evt = document.createEvent('Event'); evt.initEvent('change', true, true); }
                        inp.dispatchEvent(evt);
                    }
                },null);
        }
        sp.appendChild(sel);
        disable_prop(inp);
        sp.appendChild(inp);
        sp.style.display=disp;
        obj.appendChild(sp);
    }
    function display(mode){
        if(mode==='show')
            if(opts_brd_b.style.display==='none') opts_brd_b.style.display='block';
            else{opts_brd.parentNode.style.display='block';}
        if(mode==='hide')
            if(opts_brd.parentNode.style.display!='none') opts_brd.parentNode.style.display='none';
            else opts_brd_b.style.display='none';
    }
    function get_config(){
        values = {};
        for(var key in datas){
            var elem = document.getElementById(key);
            if(elem){ values[key] = elem.value; }
            else{console.warn("No "+key+" found.");}
        }
        dict.init_params({"db": values["dict_db"], "dictionary": values["dict_src"], 
                          "host": values["socket_host"], "port": parseInt(values["socket_port"]), 
                          "sl": values["lang_f"], "hl": values["lang_t"], "tl": values["lang_t"]});
        return values;
    }
    function set_sel_vl(sel){
        get_opt(["sel_"+sel.id], function(ky, vl){
                var opts = Array.prototype.slice.call(sel.options);
                var id = opts.map(function(el){return (el.value===vl);}).indexOf(true);
                if(id!=-1) { sel.selectedIndex = id;
                             draw_deps(sel); 
                             get_config(); }
            });
    }
    function makepos(x){
        x = x||0;
        var re = /.+?\..+?/, result = x;
        if(re.test(x)) result = parseFloat(x);
        else result = parseInt(x);
        if(isNaN(x) && x<0) result = 0;
        return result;
    }
    function get_opt(keys, callback, evt){
    }
    function set_opt(key, p){
    }
    function fill_params(callbacks){
        var sels = [];
        for(var key in datas){
            type = typeof(datas[key][0]);
            if(type=="object") sels.push(create_select(opts_brd, datas[key][1], datas[key][0], key, datas[key][2]));
            if(type=="string") create_input(opts_brd, datas[key][1], datas[key][0], key, datas[key][2]);
        }
        get_config();
        sels.map(function(sl){set_sel_vl(sl);});
    }
    function add_dbs(sel, _nm, txt){
        var _txt = txt.replace(/\ /g, "_._").replace(/(\s|\0)+/g, "\n")
                      .replace(/_\._/g, " ").replace(/\"/g, "");
        var count = parseInt(txt.replace(/\s+/g, " ")
                                .replace(/(.*110.+?)(\d*)(.+?databases present.*)/, "$2"));
        var arr = _txt.split("\n").filter(function(el){return el!='';});
        var start = arr.indexOf("250 ok")-2;
        if(isNaN(count) || start<0) { console.warn("No db count or start in "+txt); return; }
        var itms = [];
        Array.prototype.slice.call(sel.options).map(function(el){sel.removeChild(el);});
        sel.appendChild(_nm);
        for(var i = start; i>(start-count) && i>0; i--){
                var itms = arr[i].split(" ");
                var nm  = document.createElement("option");
                nm.value = itms[0];
                nm.textContent = arr[i].replace(itms[0]+" ", '');
                sel.appendChild(nm);
        }
        sel.addEventListener("change", function(evt){
                            var p = {};
                            p['dict'] = evt.target.options[evt.target.selectedIndex].value;
                            dict.init_params(p);}, true);
        set_sel_vl(sel);
    }
    function remove_key(key){
        if(storage){
            storage.removeItem(key);
        } else if(crstorage) {
            var keys = [];
            keys.push(key);
            crstorage.remove(keys, function(){
                }) 
        }
    }

    function get_all_itms(callback){
        if(storage) {
            var items = {}; var i = 0; var key = null;
            for (;key = storage.key(i); i++) items[key] = storage.getItem(key);
            callback(items);
            return;
        }
        if(crstorage) crstorage.get(null, function(items) {
                callback(items);
        });
    } 
    function getpp(){
        currentpp = {'page':0, 'percent':0};
        var prckey = filename+"_prc", pnmkey = filename+"_pnm";
        var ps = {};
        ps[prckey] = 'percent';
        ps[pnmkey] = 'page';
        get_opt(Object.keys(ps), function(key, val){
                currentpp[ps[key]] = makepos(val);
            }, 'got_pp');
    }
    fill_params();
    return{
            display:function(mode){
                display(mode);
            },
            config:function(){
                return values;
            },
            bookfile:function(){
                return file;
            },
            remove_opt:function(key){
                remove_key(filename+"_"+key);
            },
            set_opt:function(key, val, file){
                var param;
                if(file) param = filename+"_"+key;
                else param = key;
                set_opt(param, val);
            },
            remove_old:function(){
                get_all_itms(remove_old);
            },
            get_opt:function(key, callback, file){
                var ps = [];
                if(file) ps.push(filename+"_"+key);
                else ps.push(key);
                get_opt(ps, function(ky, vl){callback(vl);}, null);
            },
            getpp:function(){
                getpp();
            },
            setpercent:function(percent){
                if(isNaN(percent)) currentpp['percent'] = 0;
                else currentpp['percent'] = percent;
                lbl.textContent = parseInt(percent)+"% of current chapter";
            },
            msg:function(text){
                if(text) { lbl.textContent = text; return null;}
                else return lbl.textContent;
            },
            getpercent:function(){
                return currentpp['percent'];
            },
            setpage:function(page){
                if(isNaN(page)) currentpp['page'] = 0;
                else currentpp['page'] = page;
            },
            getpage:function(){
                return currentpp['page'];
            },
            filename:function(){
                return filename;
            }
    };
  }
);
